package com.fallsvc.re.javasesets.priorityqueue;

/**
 * @auther falls_vc
 * description:
 * @date 2025/10/20  20:31
 */

public class MyPriorityQueue {

    // 堆的向下调整 小根堆
    public void shiftDown(int[] array, int parent) {
        // child先标记parent的左孩子，因为parent可能右左没有右
        int child = 2 * parent + 1;
        int size = array.length;
        while (child < size) {
            // 如果右孩子存在，找到左右孩子中较小的孩子,用child进行标记
            if (child + 1 < size && array[child + 1] < array[child]) {
                child += 1;
            }
            // 如果双亲比其最小的孩子还小，说明该结构已经满足堆的特性了
            if (array[parent] <= array[child]) {
                break;
            } else {
                // 将双亲与较小的孩子交换
                int t = array[parent];
                array[parent] = array[child];
                array[child] = t;
                // parent中大的元素往下移动，可能会造成子树不满足堆的性质，因此需要继续向下调整
                parent = child;
                child = parent * 2 + 1;
            }
        }
    }

    // 建堆
    public void createHeap(int[] array) {
        // 找倒数第一个非叶子节点，从该节点位置开始往前一直到根节点，遇到一个节点，应用向下调整
        int root = (array.length - 2) >> 1;
       while(root >= 0) {
           shiftDown(array,root);
           root--;
       }
    }

    // 向上调整 小根堆
    public void shiftUp(int[] array, int child) {
        // 找到child的双亲
        int parent = (child - 1) / 2;
        while (child > 0) {
            // 如果双亲比孩子小，parent满足堆的性质，调整结束
            if (array[parent] < array[child]) {
                break;
            } else {
                // 将双亲与孩子节点进行交换
                int t = array[parent];
                array[parent] = array[child];
                array[child] = t;
                // 大的元素向下移动，可能到值子树不满足对的性质，因此需要继续向上调增
                child = parent;
                parent = (child - 1) / 1;
            }
        }
    }
}